package com.zhang.chatcenter.chat;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.*;
import java.security.cert.CertificateException;

/**
 * 这里的channel特指SocketChannel
 *
 * @author zhangFanJun
 * @date 2024-02-27 14:57
 **/
@Slf4j
@Component
public class WebSocketServerInitializer extends ChannelInitializer<SocketChannel> {

    @Resource
    private WebSocketInBoundHandler webSocketInBoundHandler;

    /**
     * 该方法在客户端socket.onopen建立连接的时候生效
     */
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {

        log.info("初始化SocketChannel的ChannelPipeline");
//        ssl(socketChannel);

        ChannelPipeline pipeline = socketChannel.pipeline();
        pipeline.addLast(new HttpServerCodec());
        pipeline.addLast(new HttpObjectAggregator(65536));
        pipeline.addLast(new WebSocketServerProtocolHandler("/chat"));
        pipeline.addLast(webSocketInBoundHandler);
        pipeline.addLast(new WebSocketOutboundHandler());
        pipeline.addLast(new WebSocketOutboundHandler2());
    }

    /**
     * 如果nginx没有接入https的时候可以采用这个ssl完成https访问配置
     * */
    private void ssl(SocketChannel socketChannel) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException {

        // 加载密钥库文件
        String keyStorePassword = "123456";
        KeyStore keyStore = KeyStore.getInstance("JKS");
        String keyStoreFilePath = "D:\\data\\cer\\chat.jks";
        try (FileInputStream inputStream = new FileInputStream(keyStoreFilePath)) {
            keyStore.load(inputStream, keyStorePassword.toCharArray());
        }

        // 创建密钥管理工厂
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());

        // 创建SSL上下文,SSLv3,TLS
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(keyManagerFactory.getKeyManagers(), null, null);

        //下面多种addLast配置方式

        SslContext ssl = SslContextBuilder.forServer(keyManagerFactory).build();
        SslHandler sslHandler = ssl.newHandler(socketChannel.alloc());
//        pipeline.addLast(new SslHandler(ssl.newEngine(socketChannel.alloc())));
//        socketChannel.pipeline().addLast(sslHandler);

        SSLEngine sslEngine = sslContext.createSSLEngine();
        sslEngine.setNeedClientAuth(false);
        sslEngine.setUseClientMode(false);
        socketChannel.pipeline().addLast(new SslHandler(sslEngine));
    }

}
